#include "com_hardware_mrd_AkRadio.h"

#define LOG_TAG "AkRadio"
//#undef LOG
//#include <utils/Log.h>

#include<android/log.h>

#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, fmt, ##args)
#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, fmt, ##args)
#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, fmt, ##args)
#define LOGW(fmt, args...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, fmt, ##args)


#include <errno.h>
#include <fcntl.h>
#include <termios.h>
#include <pthread.h>
#include <stdlib.h>

#include "ak_radio.h"


#define IF_USE_CODE_AK 0 
static int checkCode(){
#if IF_USE_CODE_AK
	int ret = -1;
	int code;
	int codeReturn;
	char buf[4] = {rand(),rand(), rand(),rand()};
	
	int fd = open("/sys/class/ak/keypad/ak", O_RDWR | O_NONBLOCK, 0666);
	if(fd < 0){
		LOGE("open '/sys/class/ak/keypad/ak' error(%d)", errno);
		return ret;
	}
	codeReturn = write(fd, buf, sizeof(buf));			
	close(fd);

	code = (((buf[0] ^ 0x47) << 0) | ((buf[1] ^ 0xa4) << 8) | ((buf[2] ^ 0xa7) << 16) |((buf[3] ^ 0x74) << 24));
	
	if (code == codeReturn){
		ret = 0;
	}
	return ret;
#else
	return 0;
#endif
}
JNIEXPORT jint JNICALL Java_com_hardware_mrd_AkRadio_nativeSendMSCCommand(JNIEnv *env, jobject thiz, jint value)
{
	static jmethodID mscCallback;
	switch(value)
	{
	case com_hardware_mrd_AkRadio_MSC_TUNER:
		{
			int index;
			char buf[4] = {0};
			int fd = open("/sys/class/ak/source/index", O_RDWR | O_NONBLOCK, 0666);
			if(fd < 0){
				LOGE("open '/sys/class/ak/source/index' error(%d)", errno);
				return -1;
			}
			read(fd, buf, sizeof(buf));
			switch((index = atoi(buf)))
			{
//			case 0x1: // DVD
//				{
//					struct termios tio;
//					unsigned char tx[] = {0x03, 0x42, 0x00, 0xba};
//					int fd = open("/dev/ttyvk3x0", O_RDWR | O_NONBLOCK | O_NOCTTY, 0666);
//					if(fd < 0){
//						LOGE("open '/dev/ttyvk3x0' error(%d)", errno);
//						break;
//					}
//					fcntl(fd, F_SETFL, 0);
//					tcgetattr(fd, &tio);
//					cfmakeraw(&tio);
//					cfsetospeed(&tio, B19200);
//					cfsetispeed(&tio, B19200);
//					if(tcsetattr(fd, TCSAFLUSH, &tio)){
//						LOGE("tcsetattr failed");
//						close(fd);
//						break;
//					}
//					write(fd, tx, sizeof(tx));
//					close(fd);
//				}
//				break;
			case 0x7: // SD
				if(!mscCallback)
					mscCallback = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, thiz), "mscCallback", "(I)V");
				(*env)->CallVoidMethod(env, thiz, mscCallback, 0x7);
				break;
			default:
				break;
			}
			write(fd, "0", 2);
			close(fd);
		}
		break;
	default:
		return -1;
	}
	return 0;
}

struct AkRadio{
	unsigned int mask;
	JavaVM *jvm;
	jobject thiz;
	jclass clazz;
	int fd;
	pthread_t tid;
	unsigned int texit;
	unsigned int open_num;
	jfieldID mMRDBand;
	jfieldID mMRDNumber;
	jfieldID mMRDFreqency;
	jfieldID mMRDStrength;
	jfieldID mMRDFlag;
	jfieldID mMRDFreqs;
	jfieldID mMRDRegion;
	jfieldID mMRDParam;
	jfieldID mMRDRdsFlag;
	jfieldID mMRDRdsPty;
	jfieldID mMRDRdsPs;
	jfieldID mMRDRdsRt;
	jfieldID mMRDRdsPslist;
	jfieldID mMRDRdsDinfo;
	jfieldID mMRDRdsPtyType;

	jfieldID mFreqMax;
	jfieldID mFreqMin;
};

static void *radio_thread(void *arg)
{
	struct AkRadio *mrd = (struct AkRadio *)arg;
	JavaVM *jvm = mrd->jvm;
	JNIEnv *env;
	jmethodID mrdCallback;
	(*jvm)->AttachCurrentThread(jvm, &env, NULL);
	mrdCallback = (*env)->GetMethodID(env, mrd->clazz, "mrdCallback", "(I)V");
	while(!mrd->texit){
		unsigned int event = mrd->mask;
		if((ioctl(mrd->fd, AK_RADIO_WAIT_EVENT, &event) == 0) && event){
			if (mrdCallback){
				LOGW("%s callbackup 0x%08x", __func__, event);
				(*env)->CallVoidMethod(env, mrd->thiz, mrdCallback, event);
			}
		}
	}
	(*jvm)->DetachCurrentThread(jvm);
	return NULL;
}

JNIEXPORT jint JNICALL Java_com_hardware_mrd_AkRadio_nativeSendMRDCommand(JNIEnv *env, jobject thiz, jint value)
{
	static struct AkRadio mrd = {
		.fd = -1,
		.open_num = 0,
	};
	switch(value)
	{
	case com_hardware_mrd_AkRadio_MRD_READ:
		break;
	case com_hardware_mrd_AkRadio_MRD_READ_BAND:
		if(mrd.fd >= 0){
			unsigned char band;
			if(ioctl(mrd.fd, AK_RADIO_READ_BAND, &band) == 0){
				if(!mrd.mMRDBand)
					mrd.mMRDBand = (*env)->GetFieldID(env, mrd.clazz, "mMRDBand", "B");
				(*env)->SetByteField(env, mrd.thiz, mrd.mMRDBand, band);
			}
		}
		break;
	case com_hardware_mrd_AkRadio_MRD_READ_NAMBER:
		if(mrd.fd >= 0){
			unsigned char number;
			if(ioctl(mrd.fd, AK_RADIO_READ_NAMBER, &number) == 0){
				if(!mrd.mMRDNumber)
					mrd.mMRDNumber = (*env)->GetFieldID(env, mrd.clazz, "mMRDNumber", "B");
				(*env)->SetByteField(env, mrd.thiz, mrd.mMRDNumber, number);
			}
		}
		break;
	case com_hardware_mrd_AkRadio_MRD_READ_FREQENCY:
		if(mrd.fd >= 0){
			unsigned short freqency;
			if(ioctl(mrd.fd, AK_RADIO_READ_FREQENCY, &freqency) == 0){
				if(!mrd.mMRDFreqency)
					mrd.mMRDFreqency = (*env)->GetFieldID(env, mrd.clazz, "mMRDFreqency", "S");
				(*env)->SetShortField(env, mrd.thiz, mrd.mMRDFreqency, freqency);
			}
		}
		break;
	case com_hardware_mrd_AkRadio_MRD_READ_STRENGTH:
		if(mrd.fd >= 0){
			unsigned char strength;
			if(ioctl(mrd.fd, AK_RADIO_READ_STRENGTH, &strength) == 0){
				if(!mrd.mMRDStrength)
					mrd.mMRDStrength = (*env)->GetFieldID(env, mrd.clazz, "mMRDStrength", "B");
				(*env)->SetByteField(env, mrd.thiz, mrd.mMRDStrength, strength);
			}
		}
		break;
	case com_hardware_mrd_AkRadio_MRD_READ_FLAG:
		if(mrd.fd >= 0){
			unsigned char flag;
			if(ioctl(mrd.fd, AK_RADIO_READ_FLAG, &flag) == 0){
				if(!mrd.mMRDFlag)
					mrd.mMRDFlag = (*env)->GetFieldID(env, mrd.clazz, "mMRDFlag", "B");
				(*env)->SetByteField(env, mrd.thiz, mrd.mMRDFlag, flag);
			}
		}
		break;
	case com_hardware_mrd_AkRadio_MRD_READ_FREQS:
		if(mrd.fd >= 0){
			unsigned short freqs[12];
			if(ioctl(mrd.fd, AK_RADIO_READ_FREQS, freqs) == 0){
				if(!mrd.mMRDFreqs)
					mrd.mMRDFreqs = (*env)->GetFieldID(env, mrd.clazz, "mMRDFreqs", "[S");
				jshortArray arr = (jshortArray)(*env)->GetObjectField(env, mrd.thiz, mrd.mMRDFreqs);
				(*env)->SetShortArrayRegion(env, arr, 0, 12, (jshort *)freqs);
			}
		}
		break;
	case com_hardware_mrd_AkRadio_MRD_READ_REGION:
		if(mrd.fd >= 0){
			unsigned char region;
			if(ioctl(mrd.fd, AK_RADIO_READ_STRENGTH, &region) == 0){
				if(!mrd.mMRDRegion)
					mrd.mMRDRegion = (*env)->GetFieldID(env, mrd.clazz, "mMRDRegion", "B");
				(*env)->SetByteField(env, mrd.thiz, mrd.mMRDRegion, region);
			}
		}
		break;
	case com_hardware_mrd_AkRadio_MRD_READ_PARAM:
		if(mrd.fd >= 0){
			unsigned char param[4];
			if(ioctl(mrd.fd, AK_RADIO_READ_PARAM, param) == 0){
				if(!mrd.mMRDParam)
					mrd.mMRDParam = (*env)->GetFieldID(env, mrd.clazz, "mMRDParam", "[B");
				jbyteArray arr = (jbyteArray)(*env)->GetObjectField(env, mrd.thiz, mrd.mMRDParam);
				(*env)->SetByteArrayRegion(env, arr, 0, 4, (jbyte *)param);
			}
		}
		break;
	case com_hardware_mrd_AkRadio_MRD_WRITE_BAND:
		if(mrd.fd >= 0){
			unsigned char band;
			if(!mrd.mMRDBand)
				mrd.mMRDBand = (*env)->GetFieldID(env, mrd.clazz, "mMRDBand", "B");
			band = (*env)->GetByteField(env, mrd.thiz, mrd.mMRDBand);
			ioctl(mrd.fd, AK_RADIO_WRITE_BAND, &band);
		}
		break;
	case com_hardware_mrd_AkRadio_MRD_AS:
		if(mrd.fd >= 0)
			ioctl(mrd.fd, AK_RADIO_AS, NULL);
		break;
	case com_hardware_mrd_AkRadio_MRD_PS:
		if(mrd.fd >= 0)
			ioctl(mrd.fd, AK_RADIO_PS, NULL);
		break;
	case com_hardware_mrd_AkRadio_MRD_SCAN:
		if(mrd.fd >= 0)
			ioctl(mrd.fd, AK_RADIO_SCAN, NULL);
		break;
	case com_hardware_mrd_AkRadio_MRD_SEEK_UP:
		if(mrd.fd >= 0)
			ioctl(mrd.fd, AK_RADIO_SEEK_UP, NULL);
		break;
	case com_hardware_mrd_AkRadio_MRD_SEEK_DOWN:
		if(mrd.fd >= 0)
			ioctl(mrd.fd, AK_RADIO_SEEK_DOWN, NULL);
		break;
	case com_hardware_mrd_AkRadio_MRD_STEP_UP:
		if(mrd.fd >= 0)
			ioctl(mrd.fd, AK_RADIO_STEP_UP, NULL);
		break;
	case com_hardware_mrd_AkRadio_MRD_STEP_DOWN:
		if(mrd.fd >= 0)
			ioctl(mrd.fd, AK_RADIO_STEP_DOWN, NULL);
		break;
	case com_hardware_mrd_AkRadio_MRD_SCAN_STOP:
		if(mrd.fd >= 0)
			ioctl(mrd.fd, AK_RADIO_SCAN_STOP, NULL);
		break;
	case com_hardware_mrd_AkRadio_MRD_WRITE_LOCDX:
		if(mrd.fd >= 0){
			unsigned char flag;
			if(!mrd.mMRDFlag)
				mrd.mMRDFlag = (*env)->GetFieldID(env, mrd.clazz, "mMRDFlag", "B");
			flag = !!((*env)->GetByteField(env, mrd.thiz, mrd.mMRDFlag) & AK_RADIO_INFO_FLAG_LOCDX);
			ioctl(mrd.fd, AK_RADIO_WRITE_LOCDX, &flag);
		}
		break;
	case com_hardware_mrd_AkRadio_MRD_PLAY:
		if(mrd.fd >= 0){
			unsigned char number;
			if(!mrd.mMRDNumber)
				mrd.mMRDNumber = (*env)->GetFieldID(env, mrd.clazz, "mMRDNumber", "B");
			number = (*env)->GetByteField(env, mrd.thiz, mrd.mMRDNumber);
			ioctl(mrd.fd, AK_RADIO_PLAY, &number);
		}
		break;
	case com_hardware_mrd_AkRadio_MRD_SAVE:
		if(mrd.fd >= 0){
			unsigned char number;
			if(!mrd.mMRDNumber)
				mrd.mMRDNumber = (*env)->GetFieldID(env, mrd.clazz, "mMRDNumber", "B");
			number = (*env)->GetByteField(env, mrd.thiz, mrd.mMRDNumber);
			ioctl(mrd.fd, AK_RADIO_SAVE, &number);
		}
		break;
	case com_hardware_mrd_AkRadio_MRD_WRITE_REGION:
		if(mrd.fd >= 0){
			unsigned char region;
			if(!mrd.mMRDRegion)
				mrd.mMRDRegion = (*env)->GetFieldID(env, mrd.clazz, "mMRDRegion", "B");
			region = (*env)->GetByteField(env, mrd.thiz, mrd.mMRDRegion);
			ioctl(mrd.fd, AK_RADIO_WRITE_REGION, &region);
		}
		break;
	case com_hardware_mrd_AkRadio_MRD_WRITE_FREQENCY:
		if(mrd.fd >= 0){
			unsigned short freqency;
			if(!mrd.mMRDFreqency)
				mrd.mMRDFreqency = (*env)->GetFieldID(env, mrd.clazz, "mMRDFreqency", "S");
			freqency = (*env)->GetShortField(env, mrd.thiz, mrd.mMRDFreqency);
			ioctl(mrd.fd, AK_RADIO_WRITE_FREQENCY, &freqency);
		}
		break;
	case com_hardware_mrd_AkRadio_MRD_WRITE_PARAM:
		if(mrd.fd >= 0){
			unsigned char param[4];
			if(!mrd.mMRDParam)
				mrd.mMRDParam = (*env)->GetFieldID(env, mrd.clazz, "mMRDParam", "[B");
			jbyteArray arr = (jbyteArray)(*env)->GetObjectField(env, mrd.thiz, mrd.mMRDParam);
			(*env)->GetByteArrayRegion(env, arr, 0, 4, (jbyte *)param);
			ioctl(mrd.fd, AK_RADIO_WRITE_PARAM, param);
		}
		break;
	case com_hardware_mrd_AkRadio_MRD_INFO:
		if(mrd.fd >= 0)
			ioctl(mrd.fd, AK_RADIO_INFO, NULL);
		break;
	case com_hardware_mrd_AkRadio_MRD_READ_RDS:
		break;
	case com_hardware_mrd_AkRadio_MRD_READ_RDS_FLAG:
		if(mrd.fd >= 0){
			unsigned char flag;
			if(ioctl(mrd.fd, AK_RADIO_READ_RDS_FLAG, &flag) == 0){
				if(!mrd.mMRDRdsFlag)
					mrd.mMRDRdsFlag = (*env)->GetFieldID(env, mrd.clazz, "mMRDRdsFlag", "B");
				(*env)->SetByteField(env, mrd.thiz, mrd.mMRDRdsFlag, flag);
			}
		}
		break;
	case com_hardware_mrd_AkRadio_MRD_READ_RDS_PTY:
		if(mrd.fd >= 0){
			unsigned char pty[2];
			if(ioctl(mrd.fd, AK_RADIO_READ_RDS_PTY, pty) == 0){
				if(!mrd.mMRDRdsPty)
					mrd.mMRDRdsPty = (*env)->GetFieldID(env, mrd.clazz, "mMRDRdsPty", "[B");
				jbyteArray arr = (jbyteArray)(*env)->GetObjectField(env, mrd.thiz, mrd.mMRDRdsPty);
				(*env)->SetByteArrayRegion(env, arr, 0, 2, (jbyte *)pty);
			}
		}
		break;
	case com_hardware_mrd_AkRadio_MRD_READ_RDS_PS:
		if(mrd.fd >= 0){
			unsigned char ps[8];
			if(ioctl(mrd.fd, AK_RADIO_READ_RDS_PS, ps) == 0){
				if(!mrd.mMRDRdsPs)
					mrd.mMRDRdsPs = (*env)->GetFieldID(env, mrd.clazz, "mMRDRdsPs", "[B");
				jbyteArray arr = (jbyteArray)(*env)->GetObjectField(env, mrd.thiz, mrd.mMRDRdsPs);
				(*env)->SetByteArrayRegion(env, arr, 0, 8, (jbyte *)ps);
			}
		}
		break;
	case com_hardware_mrd_AkRadio_MRD_READ_RDS_RT:
		if(mrd.fd >= 0){
			unsigned char rt[64];
			if(ioctl(mrd.fd, AK_RADIO_READ_RDS_RT, rt) == 0){
				if(!mrd.mMRDRdsRt)
					mrd.mMRDRdsRt = (*env)->GetFieldID(env, mrd.clazz, "mMRDRdsRt", "[B");
				jbyteArray arr = (jbyteArray)(*env)->GetObjectField(env, mrd.thiz, mrd.mMRDRdsRt);
				(*env)->SetByteArrayRegion(env, arr, 0, 64, (jbyte *)rt);
			}
		}
		break;
	case com_hardware_mrd_AkRadio_MRD_READ_RDS_PSLIST:
		if(mrd.fd >= 0){
			int i;
			unsigned char pslist[12][8];
			if(ioctl(mrd.fd, AK_RADIO_READ_RDS_PSLIST, pslist) == 0){
				if(!mrd.mMRDRdsPslist)
					mrd.mMRDRdsPslist = (*env)->GetFieldID(env, mrd.clazz, "mMRDRdsPslist", "[[B");
				jobjectArray arr = (jobjectArray)(*env)->GetObjectField(env, mrd.thiz, mrd.mMRDRdsPslist);
				for(i = 0; i < 12; i++){
					jbyteArray arri = (jbyteArray)(*env)->GetObjectArrayElement(env, arr, i);
					(*env)->SetByteArrayRegion(env, arri, 0, 8, (jbyte *)pslist[i]);
				}
			}
		}
		break;
	case com_hardware_mrd_AkRadio_MRD_RDS_AF_OFF:
		if(mrd.fd >= 0)
			ioctl(mrd.fd, AK_RADIO_RDS_AF_OFF, NULL);
		break;
	case com_hardware_mrd_AkRadio_MRD_RDS_AF_ON:
		if(mrd.fd >= 0)
			ioctl(mrd.fd, AK_RADIO_RDS_AF_ON, NULL);
		break;
	case com_hardware_mrd_AkRadio_MRD_RDS_TA_OFF:
		if(mrd.fd >= 0)
			ioctl(mrd.fd, AK_RADIO_RDS_TA_OFF, NULL);
		break;
	case com_hardware_mrd_AkRadio_MRD_RDS_TA_ON:
		if(mrd.fd >= 0)
			ioctl(mrd.fd, AK_RADIO_RDS_TA_ON, NULL);
		break;
	case com_hardware_mrd_AkRadio_MRD_RDS_EON_OFF:
		if(mrd.fd >= 0)
			ioctl(mrd.fd, AK_RADIO_RDS_EON_OFF, NULL);
		break;
	case com_hardware_mrd_AkRadio_MRD_RDS_EON_ON:
		if(mrd.fd >= 0)
			ioctl(mrd.fd, AK_RADIO_RDS_EON_ON, NULL);
		break;
	case com_hardware_mrd_AkRadio_MRD_RDS_REG_OFF:
		if(mrd.fd >= 0)
			ioctl(mrd.fd, AK_RADIO_RDS_REG_OFF, NULL);
		break;
	case com_hardware_mrd_AkRadio_MRD_RDS_REG_ON:
		if(mrd.fd >= 0)
			ioctl(mrd.fd, AK_RADIO_RDS_REG_ON, NULL);
		break;
	case com_hardware_mrd_AkRadio_MRD_RDS_PTY_OFF:
		if(mrd.fd >= 0)
			ioctl(mrd.fd, AK_RADIO_RDS_PTY_OFF, NULL);
		break;
	case com_hardware_mrd_AkRadio_MRD_RDS_PTY_ON:
		if(mrd.fd >= 0)
			ioctl(mrd.fd, AK_RADIO_RDS_PTY_ON, NULL);
		break;
	case com_hardware_mrd_AkRadio_MRD_RDS_PTY_SEEK_UP:
		if(mrd.fd >= 0)
			ioctl(mrd.fd, AK_RADIO_RDS_PTY_SEEK_UP, NULL);
		break;
	case com_hardware_mrd_AkRadio_MRD_RDS_PTY_SEEK_DOWN:
		if(mrd.fd >= 0)
			ioctl(mrd.fd, AK_RADIO_RDS_PTY_SEEK_DOWN, NULL);
		break;
	case com_hardware_mrd_AkRadio_MRD_RDS_PTY_TYPE:
		if(mrd.fd >= 0){
			unsigned char pty_type;
			if(!mrd.mMRDRdsPtyType)
				mrd.mMRDRdsPtyType = (*env)->GetFieldID(env, mrd.clazz, "mMRDRdsPtyType", "B");
			pty_type = (*env)->GetByteField(env, mrd.thiz, mrd.mMRDRdsPtyType);
			ioctl(mrd.fd, AK_RADIO_RDS_PTY_TYPE, &pty_type);
		}
		break;
	case com_hardware_mrd_AkRadio_MRD_RDS_INFO:
		if(mrd.fd >= 0)
			ioctl(mrd.fd, AK_RADIO_RDS_INFO, NULL);
		break;
	case com_hardware_mrd_AkRadio_MRD_RDS_READ_FREQ_RANGE:
		if(mrd.fd >= 0){
			unsigned int range;
			ioctl(mrd.fd, AK_RADIO_READ_FREQ_RANGE, &range);
			if(!mrd.mFreqMax)
					mrd.mFreqMax = (*env)->GetFieldID(env, mrd.clazz, "mFreqMax", "S");
			(*env)->SetShortField(env, mrd.thiz, mrd.mFreqMax, (unsigned short)((range >> 16) & 0xffff) );

			if(!mrd.mFreqMin)
					mrd.mFreqMin = (*env)->GetFieldID(env, mrd.clazz, "mFreqMin", "S");
			(*env)->SetShortField(env, mrd.thiz, mrd.mFreqMin, (unsigned short)( range & 0xffff ));

		}
		break;
	case com_hardware_mrd_AkRadio_MRD_OPEN:
		if (mrd.fd > 0){	//close first
			mrd.texit = 1;
			pthread_join(mrd.tid, NULL);
			(*env)->DeleteGlobalRef(env, mrd.clazz);
			(*env)->DeleteGlobalRef(env, mrd.thiz);
			close(mrd.fd);
			mrd.fd = -1;
		}
		
		if(mrd.fd < 0){
			jclass clazz;
			jfieldID mMRDMask;
			
			if (checkCode() != 0){
				LOGE("checkCode error!!!!!!!!!!!!!!!!!!");
				return -1;
			}
			
			mrd.fd = open("/dev/radio", O_RDWR, 0666);
			if(mrd.fd < 0){
				LOGE("open '/dev/radio' error(%d)", errno);
				return -1;
			}
			LOGD("open '/dev/radio' ok");
			clazz = (*env)->GetObjectClass(env, thiz);
			mMRDMask = (*env)->GetFieldID(env, clazz, "mMRDMask", "I");
			mrd.mask = (*env)->GetIntField(env, thiz, mMRDMask);
			(*env)->GetJavaVM(env, &mrd.jvm);
			mrd.thiz = (*env)->NewGlobalRef(env, thiz);
			mrd.clazz = (*env)->NewGlobalRef(env, clazz);
			mrd.texit = 0;
			pthread_create(&mrd.tid, NULL, radio_thread, &mrd);
		}
		
		++mrd.open_num;
		break;
	case com_hardware_mrd_AkRadio_MRD_CLOSE:
		if(mrd.fd >= 0){
			--mrd.open_num;
			if (mrd.open_num <= 0){
				mrd.texit = 1;
				pthread_join(mrd.tid, NULL);
				(*env)->DeleteGlobalRef(env, mrd.clazz);
				(*env)->DeleteGlobalRef(env, mrd.thiz);
				close(mrd.fd);
				mrd.fd = -1;
				mrd.open_num = 0;
			}
		}
		break;
	case com_hardware_mrd_AkRadio_MRD_READ_DEBUG_INFO:
		break;
	case com_hardware_mrd_AkRadio_MRD_READ_RDS_DEBUG_INFO:
		if(mrd.fd >= 0){
			unsigned char dinfo[32];
			if(ioctl(mrd.fd, AK_RADIO_READ_RDS_DEBUG_INFO, dinfo) == 0){
				if(!mrd.mMRDRdsDinfo)
					mrd.mMRDRdsDinfo = (*env)->GetFieldID(env, mrd.clazz, "mMRDRdsDinfo", "[B");
				jbyteArray arr = (jbyteArray)(*env)->GetObjectField(env, mrd.thiz, mrd.mMRDRdsDinfo);
				(*env)->SetByteArrayRegion(env, arr, 0, 32, (jbyte *)dinfo);
			}
		}
		break;
	default:
		return -1;
	}
	return 0;
}
